#pragma once
#include<iostream>
#include<cstring>
#include<cassert>
using namespace std;
namespace ddsm
{
	template<typename T>
	class vector
	{
	public:

		vector() = default;
		//构造函数，迭代器区间初始化

		template<typename inputIterator>
		vector(const inputIterator& begin, const inputIterator& end)
		//支持任意容器的迭代器初始化:string
			//左闭右开
		{
			reserve(end-begin);
			inputIterator it = begin;
			while (it != end)
			{
				push_back(*it);
				++it;
			}
		}

		//整形匹配
		vector(int n, const T& val = T())
		{
			reserve(n);
			//reserve不改变capacity
			for (int i = 0; i < n; i++)
			{
				_start[i] = val;
			}
			//用多少申请多少，size等于容量
			_finish = _end_of_storage = _start + n;
		}
		//自定义类型匹配
		vector(size_t n,const T& val = T())
		{
			reserve(n);
			for (size_t i = 0; i < n; i++)
			{
				_start[i] = val;
			}
		}
		//拷贝构造
		vector(const vector<T>& t)
			//目标，将t深拷贝给*this
		{
			reserve(t.capacity());
			for (const auto& e : t)
			{
				push_back(e);
			}
		}
			////防止迭代器失效
			//int _len = t.size();
			//int _capacity = t.capacity();
			
			//将原t内容拷贝到tem
			//iterator tem = new T[_capacity];
			//iterator ptem = tem;
			//iterator start = t._start;

			//while (start != t._finish)
			//{
			//	*ptem = *start;
			//	++ptem;
			//	++start;
			//}

			////tem给*this
			//_start = tem;
			//_finish = _start + _len;
			//_end_of_storage = _start + _capacity;

		/*
			iterator tem = new T[capacity()];
			iterator ptem = tem;
			iterator start = t._start;

			//将原vector内容拷贝到新vector
			while (start != t._finish)
			{
				*ptem = *start;
				++ptem;
				++start;
			}*/
		void swap(vector<T> tem)
		{
			std::swap(_finish, tem._finish);
			std::swap(_start, tem._start);
			std::swap(_end_of_storage, tem._end_of_storage);
		}

		//赋值重载
		vector<T> operator=(const vector<T> tem)
			//拷贝构造创建一个临时对象，用于交换得到有效数据
			// 只要完成拷贝构造即可完成赋值重载
		{
			//现代写法
			swap(tem);
			return *this;
		}
		//迭代器
		typedef T* iterator;
		typedef const T* const_iterator;

		size_t size() const
		{
			return _finish - _start;
		}

		size_t capacity() const
		{
			return _end_of_storage - _start;
		}

		iterator begin() 
		{
			return _start;
		}

		iterator end()
		{
			return _finish;
		}

		const_iterator begin() const
		{
			return _start;
		}

		const_iterator end() const
		{
			return _finish;
		}

		//保留空间
		void reserve(int n)
		{
			//先保存size,防止_start,_finish变化，导致size无法计算
			int oldsize = size();
			//要求保留的大于现有的，扩容
			if (n > capacity())
			{
				T* tem = new T[n];
				if (_start)
				{
					for (size_t i = 0; i < oldsize; i++)
					{
						tem[i] = _start[i];
					}
				}

				if(_start)
					delete[] _start;
				_start = tem;
				_finish = _start + oldsize;
				_end_of_storage = _start + n;
			}
			//否则，不缩容
		}

		//尾插一个T对象
		void push_back(const T& t)
		{
			if (size() == capacity())
				//需要扩容
			{
				int Newcapacity = capacity() == 0 ? 4 : capacity() * 2;
				reserve(Newcapacity);
				//改变capacity,不改变size
			}
			//扩容完毕，开始尾插
			*_finish = t;
			++_finish;
		}

		//一般类型调用，可读可写
		T& operator[](size_t pos)
		{
			//空间地址有效
			assert(pos < size() && pos >= 0);

			return _start[pos];
		}

		//const对象调用的，read-only
		const T& operator[](size_t pos) const
		{
			//空间地址有效
			assert(pos < size() && pos >= 0);

			return _start[pos];
		}

		void pop_back()
		{
			assert(size() > 0);

			--_finish;
		}

		//在pos位置插入对象
		iterator insert(iterator pos, const T& t)
			//由于可能需要扩容，会发生迭代器失效，对内部而言
			//迭代器pos在扩容前后指向的对象不再相同，对外部也是同样的会发生
		{
			if (size() == capacity())
				//需要扩容
			{
				int len = pos - _start;
				int Newcapacity = capacity() == 0 ? 4 : capacity() * 2;
				reserve(Newcapacity);
				//改变capacity,不改变size

				//记录len，解决迭代器失效的问题
				pos = _start + len;
			}

			//移动对象
			iterator end = _finish;
			while (end != pos)
			{
				*end = *(end - 1);
				--end;
			}
			*pos = t;

			return pos;
		}

		//一般不会出现迭代器失效的问题
		iterator erase(iterator pos)
		{
			iterator oldpos = pos;
			iterator start = pos + 1;
			while (start < _finish)
			{
				*(start - 1) = *start;
				++start;
			}
			--_finish;
			return oldpos;
		}

		~vector()
		{
			delete[] _start;
			_finish = _end_of_storage = nullptr;
		}
	private:
		iterator _start = nullptr;
		iterator _finish = nullptr;
		iterator _end_of_storage = nullptr;
	};

	//非成员函数，流插入
	ostream& operator<<(ostream& out, vector<int> v)
	{
		for (const auto& e : v)
		{
			cout << e << " ";
		}
		cout << endl;
		return out;
	}
};